﻿using Newtonsoft.Json;
using System;

namespace FrameWork
{
   public abstract class Verification
   {
        private const string PublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXnSaaXHQZ6a5DG9YskFtT/Wcxfb6otUXvU8GFZ59RnSQH+6GbAnaj6eYZ2OwD7+CqdcGj1gnk2pGUp9ejsQRzEGhq+qvqcS3NuE/EmeM19bxDr7XoKUDaY8q/AiX7Gw7eZWx9tCD+cWSbsZW1bwuBcH4fm8Re/uQ+AFteKJgxHwIDAQAB";
        private const string OpenKey = "ac29baa0b7a2b2cc76ee96f6705cb293";
        private const string ActivationFileName = "secret.dll";
        private static System.Threading.Timer _time;
        private static string _key;
        private static string _userNum;
        private static DateTime? _timenow;
        private static readonly object LockTime = new object();

        /// <summary>
        /// 定时检查错误后触发(仅触发一次)
        /// </summary>
        /// <param name="model"></param>
        protected abstract void TimeTrigger(ActivationModel model);

        /// <summary>
        /// 验证激活码
        /// </summary>
        /// <param name="userNum">用户ID</param>
        /// <returns>验证结果</returns>
        public ActivationModel Validate(string userNum)
        {
            var model = new ActivationModel();

            if (string.IsNullOrWhiteSpace(_key))
            {
                _key = PublicTool.ReadFile(ActivationFileName);
            }

            if (_time == null)
            {
                _time = new System.Threading.Timer(TimerCallback, null, 0, 1000);
            }

            if (string.IsNullOrWhiteSpace(userNum))
            {
                model.Message = "用户信息错误";
            }
            else
            {
                model = DecryptKey(userNum, _key);
            }

            return model;
        }

        /// <summary>
        /// 写入激活码
        /// </summary>
        /// <param name="userNum">用户ID</param>
        /// <param name="key">密钥</param>
        public ActivationModel Activation(string userNum, string key)
        {
            var model = new ActivationModel();

            if (string.IsNullOrWhiteSpace(_key))
            {
                _key = PublicTool.ReadFile(ActivationFileName);
            }

            if (_time == null)
            {
                _time = new System.Threading.Timer(TimerCallback, null, 0, 1000);
            }

            if (string.IsNullOrWhiteSpace(key))
            {
                model.Message = "激活码错误";
                return model;
            }

            model = DecryptKey(userNum, key);

            if (model.Result)
            {
                PublicTool.WriteFile(ActivationFileName, _key);
            }

            return model;
        }
        private void TimerCallback(object obj)
        {
            lock (LockTime)
            {
                if (_timenow == null)
                {
                    try
                    {
                        if (PublicTool.GetTimeNow(out var timeNow)) _timenow = timeNow;
                    }
                    catch (Exception)
                    {
                        return;
                    }
                }
            }

            if (_timenow == null) return;

            _timenow = _timenow.Value.AddSeconds(1);

            if (string.IsNullOrWhiteSpace(_userNum) || string.IsNullOrWhiteSpace(_key)) return;

            var model = DecryptKey(_userNum, _key);

            if (model.Result) return;

            _time.Dispose();
            TimeTrigger(model);
        }
        private static ActivationModel DecryptKey(string userNum, string key)
        {
            var model = new ActivationModel();

            if (string.IsNullOrWhiteSpace(key))
            {
                model.Message = "激活码错误";
                return model;
            }

            lock (LockTime)
            {
                if (_timenow == null)
                {
                    try
                    {
                        if (PublicTool.GetTimeNow(out var timeNow)) _timenow = timeNow;
                    }
                    catch (Exception)
                    {
                        model.Message = "获取时间失败";
                        return model;
                    }
                }
            }

            if (_timenow == null)
            {
                model.Message = "获取时间失败";
                return model;
            }

            try
            {
                var bytes = HexAndByte.Hex2Byte(key);
                var source = AESHelper.AesDecrypt(bytes, OpenKey);
                var json = RsaHelp.DecryptString(source, PublicKey);
                json = Base64Helper.Base64ToString(json);
                model = JsonConvert.DeserializeObject<ActivationModel>(json);
            }
            catch (Exception ex)
            {
                Log4Help.Error("激活错误", ex);
            }

            if (model == null)
            {
                model = new ActivationModel();
            }

            model.Result = false;

            if (string.IsNullOrWhiteSpace(model.UserNum))
            {
                model.Message = "激活码错误";
                return model;
            }

            if (model.UserNum != userNum)
            {
                model.Message = "激活用户错误";
                return model;
            }

            if (model.EndTime != null && _timenow > model.EndTime.Value)
            {
                model.Message = "激活码已过期";
                return model;
            }

            model.Result = true;
            _userNum = model.UserNum;
            _key = key;
            return model;
        }
    }
   public class ActivationModel
   {
        /// <summary>
        /// 结果
        /// </summary>
        public bool Result { get; set; } = false;

        /// <summary>
        /// 返回消息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 用户ID
        /// </summary>
        public string UserNum { get; set; }

        /// <summary>
        /// 过期时间
        /// </summary>
        public DateTime? EndTime { get; set; }
    }
}
